home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Linux
/
Kubuntu 8.10
/
kubuntu-8.10-desktop-i386.iso
/
casper
/
filesystem.squashfs
/
usr
/
sbin
/
liloconfig
< prev
next >
Wrap
Text File
|
2008-05-15
|
22KB
|
684 lines
#!/usr/bin/perl
#
# /usr/sbin/liloconfig -- configure lilo automatically using debconf
#
# Author: Bruce Perens <bruce@Pixar.com>
# Bernd Eckenfels <ecki@debian.org>
# Vincent Renardias <vincent@ldsol.com>
# Peter Maydell <pmaydell@chiark.greenend.org.uk>
# Russell Coker <russell@coker.com.au>
# AndrΘs Roldßn <aroldan@debian.org>
#
# Maintainer: AndrΘs Roldßn <aroldan@debian.org>
# Updated on 2006/08/27 -- Artur R. Czechowski <arturcz@hell.pl>
# - Communication with user is handled via debconf
#
# Updated on 2004/07/31 -- AndrΘs Roldßn <aroldan@debian.org>
# - Added get_bitmap() to allow one choose the bitmap to use.
#
# Updated on 2003/12/20 -- AndrΘs Roldßn <aroldan@debian.org>
# - Modified get_images() to insert initrd= field when necessary.
# See Bug#224368.
#
# Updated on 2003/10/24 -- AndrΘs Roldßn <aroldan@debian.org>
# - Now liloconfig will smartly get the installed kernel images
# and put them in the configuration file.
#
# Updated on 2003/10/05 -- AndrΘs Roldßn <aroldan@debian.org>
# - Updated install= comments . See Bug#183471.
# - Not using depecrated install=/boot/*b options.
#
# Updated on 2003/08/07 -- AndrΘs Roldßn <aroldan@fluidsignal.com>
# - bitmap= field will search bitmaps on /boot
#
# Updated on 2003/04/23 -- AndrΘs Roldßn <aroldan@fluidsignal.com>
# - added menu entry for sid and sarge from debian-bootscreen.
#
# Updated on 1999/01/24 -- Vincent Renardias <vincent@ldsol.com>
# - never return 0 on error.
# - updated the template to produce a more helpfull (commentwise)
# resulting lilo.conf
#
# Updated on 1999/11/24 -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
# - added error checking of various system calls
# - added $DEBUG switch and pulled lilo.conf and fstab filenames
# out into config variables.
# - turned on Perl's -w switch and use strict subs/refs
# - now does examination of current situation up front, separated
# from the logic of what we do in various situations.
# - added check for special marker in /etc/fstab that indicates that we
# are configuring the base filesystem and shouldn't actually do anything.
#
# Updated on 2000-01-23 -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
# - fixed a (harmless) warning produced if /etc/fstab had a blank line in it
# - fixed a bug where partition number was not being pulled out of the
# /dev/hda4 string correctly.
# - added a paranoia check that the disk/device we get from fstab actually
# exist in the filesystem.
# - fixed flow-of-control problem where we simply weren't ever installing
# MBR and making partition active.
# - added & to some function calls, for consistency.
# - changed all references to /usr/doc/lilo/ to /usr/share/doc/lilo/.
# - added warning that the lilo.conf we produce does not suffice for
# complicated situations.
# - expanded some of the other prompts and explanatory text presented
# to the user.
# - added a 'ruler' to separate out questions
# - questions no longer accept anything except RET as meaning 'go with
# default answer'. [Previously, if the default answer was 'yes',
# anything not beginning with Y or y would be interpreted as 'no'.
# This is IMHO too lenient considering the consequences of getting
# it wrong...]
# - updated Maintainer, Author and Wishlist...
#
# Updated on 2000-01-25 -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
# - fixed important bug causing lilo not to install on RAID arrays.
# (Bugs #56153,#56183,#56196)
# - minor improvement to a regexp (no actual functional change) (Bug#56127)
# - expanded cryptic 'iff' comment (Bug#56127)
#
# Updates on 2001-05-04 -- Russell Coker <russell@coker.com.au>
# - more work on devfs root support
# Wishlist:
# This script is from Bruce's debian.postinst and need to be more
# intelligent. It should be possible to install lilo in the MBR, too.
# Support for systems which dual boot (esp. dual Linux/Windows) would
# also be nice, but could be complicated to get right.
###use strict 'subs';
###use strict 'refs';
#### use strict 'vars' falls over on all the global variables :->
use Debconf::Client::ConfModule qw(:all);
version('2.0');
$|=1;
fset("liloconfig/banner","seen","false");
fset("liloconfig/use_current_lilo","seen","false");
fset("liloconfig/wipe_old_liloconf","seen","false");
fset("liloconfig/instruction","seen","false");
fset("liloconfig/install_from_root_device","seen","false");
fset("liloconfig/use_lba32","seen","false");
fset("liloconfig/install_mbr","seen","false");
fset("liloconfig/make_active_partition","seen","false");
fset("liloconfig/select_bitmap","seen","false");
# Set this to 1 to disable all commands that do things to the
# hard disk (ie actually running lilo). Note that we still write
# to $LILOCONF, so you should also tweak that to get a 'safe' test
# environment.
#$DEBUG=1;
# Various files we access
$LILOCONF='/etc/lilo.conf';
$FSTAB='/etc/fstab';
subst("liloconfig/liloconf_exists","liloconf",$LILOCONF);
subst("liloconfig/lilo_warning","liloconf",$LILOCONF);
subst("liloconfig/lilo_error","liloconf",$LILOCONF);
subst("liloconfig/odd_fstab","liloconf",$LILOCONF);
subst("liloconfig/instruction","liloconf",$LILOCONF);
subst("liloconfig/fstab_broken","fstab",$FSTAB);
subst("liloconfig/odd_fstab","fstab",$FSTAB);
# Print a banner now, to give the user something to look at while
# we ferret around in the fstab...
settitle("liloconfig/maintitle");
input("low","liloconfig/banner");
# First we analyse the setup and set variables appropriately
$fstab_broken = 1; # is there a valid /etc/fstab? Assume not and prove otherwise.
$liloconf_exists = 0; # is there a preexisting lilo.conf with a non-commented out line?
$liloconf_incompatible = 0; # does lilo.conf use options not valid for this version of lilo?
$configuring_base = 0; # are we configuring the 'base' filesystem (special case)
$odd_fstab = 0; # set if we don't understand the device in the fstab
# We also set $device, $disk, $partition (assuming fstab_broken == 0)
if (-f $FSTAB)
{
# Parse fstab for the root partition...
open(FSTAB, "<$FSTAB") or die "liloconfig: couldn't open $FSTAB: $!\n";
while (<FSTAB>)
{
# Check for a magic string which indicates that we are configuring
# the base filesystem and not a real machine...
$configuring_base = 1 if /^# UNCONFIGURED FSTAB FOR BASE SYSTEM/;
next if /^#/; # ignore comment lines
s/^[ \t]+//; # remove space or tab at begin of the line
($device,$filesystem) = split(/[ \t]+/);
next unless defined $filesystem; # ignore empty lines too
# Stop if we found the root device...
if ($filesystem eq '/')
{
$fstab_broken = 0;
last;
}
}
close(FSTAB) or die "liloconfig: couldn't close $FSTAB: $!\n";
}
if (! $fstab_broken)
{
# Valid device/filesystem pair, parse them
$disk = `/usr/sbin/lilo_find_mbr $device`;
chomp($disk);
$partition = $device;
my $devfs = 0;
# Paranoia check: there should be valid /dev/ nodes for these.
# We could check for block-special-device-ness, but perhaps
# some people have symlink forests in /dev/ ?
# This check will fail on things like RAID arrays, where the
# devices don't have names like /dev/hda4. In this case we can't
# do simple autoconfiguration, but we still want to be able
# to allow the user to install their own handrolled lilo.conf.
$odd_fstab = 1 unless ($partition =~ /\d+$/ && -e $disk && -e $device);
}
# Check for an existing lilo.conf with some non-comment lines in it...
system ("grep -qsv '^#' $LILOCONF");
# Exit status is 0 iff lilo.conf exists and contains at least one non-comment line.
if ($? == 0)
{
$liloconf_exists = 1;
$liloconf_incompatible = &compatibility_check ();
}
##########################################################
# Boilerplate arrays used to produce an initial lilo.conf
##########################################################
@header = (
"# Generated by liloconfig\n",
"\n",
);
@bootheader = (
"# Specifies the boot device\n",
);
@rootheader = (
"\n",
"# Specifies the device that should be mounted as root.\n",
"# If the special name CURRENT is used, the root device is set to the\n",
"# device on which the root file system is currently mounted. If the root\n",
"# has been changed with -r , the respective device is used. If the\n",
"# variable ROOT is omitted, the root device setting contained in the\n",
"# kernel image is used. It can be changed with the rdev program.\n"
);
@boilerplate1 = (
"\n",
"# Enables map compaction:\n",
"# Tries to merge read requests for adjacent sectors into a single\n",
"# read request. This drastically reduces load time and keeps the map\n",
"# smaller. Using COMPACT is especially recommended when booting from a\n",
"# floppy disk.\n",
"# compact\n",
"\n",
"# Install the specified file as the new boot sector.\n",
"# LILO supports built in boot sectory, you only need\n",
"# to specify the type, choose one from 'text', 'menu' or 'bitmap'.\n",
"# new: install=bmp old: install=/boot/boot-bmp.b\n",
"# new: install=text old: install=/boot/boot-text.b\n",
"# new: install=menu old: install=/boot/boot-menu.b or boot.b\n",
"# default: 'menu' is default, unless you have a bitmap= line\n",
"# Note: install=bmp must be used to see the bitmap menu.\n",
"# install=menu\n",
"install=bmp\n",
"\n",
"# Specifies the number of _tenths_ of a second LILO should\n",
"# wait before booting the first image. LILO\n",
"# doesn't wait if DELAY is omitted or if DELAY is set to zero.\n",
"# delay=20\n",
"\n",
"# Prompt to use certaing image. If prompt is specified without timeout,\n",
"# boot will not take place unless you hit RETURN\n",
"prompt\n",
"timeout=50\n",
"\n",
"# Specifies the location of the map file. If MAP is\n",
"# omitted, a file /boot/map is used.\n",
"map=/boot/map\n",
"\n",
"# Specifies the VGA text mode that should be selected when\n",
"# booting. The following values are recognized (case is ignored):\n",
"# NORMAL select normal 80x25 text mode.\n",
"# EXTENDED select 80x50 text mode. The word EXTENDED can be\n",
"# abbreviated to EXT.\n",
"# ASK stop and ask for user input (at boot time).\n",
"# <number> use the corresponding text mode. A list of available modes\n",
"# can be obtained by booting with vga=ask and pressing [Enter].\n",
"vga=normal\n",
"\n",
"# Defines non-standard parameters for the specified disk.\n",
"#disk=/dev/sda\n",
"#\tbios=0x80\n",
"\n",
"# If you are using removable USB drivers (with mass-storage)\n",
"# you will need to tell LILO to not use these devices even\n",
"# if defined in /etc/fstab and referenced in /proc/partitions.\n",
"# Adjust these lines to your devices:\n",
"#\n",
"# disk=/dev/sda inaccessible\n",
"# disk=/dev/sdb inaccessible\n",
"\n"
);
@boilerplate2 = (
"# If you have another OS on this machine (say DOS),\n",
"# you can boot if by uncommenting the following lines\n",
"# (Of course, change /dev/hda2 to wherever your DOS partition is.)\n",
"# other=/dev/hda2\n",
"# label=\"MS Windows\"\n",
"\n"
);
####################
# Utility functions
####################
sub get_bitmap
{
input("high","liloconfig/select_bitmap");
go();
($ret,$val) = get("liloconfig/select_bitmap");
@bitmaps = (
[ "/boot/sarge.bmp","1,,0,2,,0","120p,173p,1,15,17","254p,432p,1,0,0" ],
[ "/boot/sid.bmp","1,,0,2,,0","120p,173p,1,15,17","254p,432p,1,0,0" ],
[ "/boot/coffee.bmp","12,,11,15,,8","385p,100p,1,10","38,2,13,1" ],
[ "/boot/debianlilo.bmp","1,,0;9,,0","106p,144p,2,9,144p","514p,144p,6,8,0" ]
);
$counter = 0;
for $ref (@bitmaps)
{
last if ($val eq @$ref[0]);
$counter++;
}
$ans = $counter;
push (@bitmapconf, "\n# Bitmap configuration for $bitmaps[$ans][0]\n");
push (@bitmapconf, "bitmap=$bitmaps[$ans][0]\n");
push (@bitmapconf, "bmp-colors=$bitmaps[$ans][1]\n");
push (@bitmapconf, "bmp-table=$bitmaps[$ans][2]\n");
push (@bitmapconf, "bmp-timer=$bitmaps[$ans][3]\n");
return @bitmapconf;
}
sub get_images
{
my @images = ();
$count = 0;
print STDERR "Searching for installed kernels and updating image entries ...\n";
push (@images, "# These images were automagically added. You may need to edit something.\n\n");
# Ignore that /vmlinuz link since it can surely be poiting to
# some /boot/vmlinuz* file
if (-e "/vmlinuz" && ! -l "/vmlinuz")
{
push (@images, "image=/vmlinuz\n");
push (@images, "\tlabel=\"Linux\"\n");
if (-e "/initrd.img")
{
push (@images, "\tinitrd=/initrd.img\n");
}
push (@images, "\tread-only\n");
push (@images, "\n");
}
# Ignore that /boot/vmlinuz link as well since it can surely be
# poiting to some /boot/vmlinuz* file
if (-e "/boot/vmlinuz" && ! -l "/boot/vmlinuz")
{
push (@images, "image=/boot/vmlinuz\n");
push (@images, "\tlabel=\"Linux 1\"\n");
if (-e "/boot/initrd.img")
{
push (@images, "\tinitrd=/boot/initrd.img\n");
}
push (@images, "\tread-only\n");
push (@images, "\n");
}
foreach $image (`/bin/ls /boot/vmlinuz*`)
{
chomp $image;
my $version = "";
my $complement = "";
if ($image =~ /vmlinuz-(\d+\.\d+\.\d+)-(.+)/)
{
$version = $1;
$complement = $2;
$label = "Lin " . $version . "img" . $count;
}
elsif ($image =~ /vmlinuz-(\d+\.\d+\.\d+)$/)
{
$version = $1;
$label = "Lin " . $version . "img" . $count;
}
else
{
$label = "Lin " . "img" . $count;
}
push (@images, "image=$image\n");
push (@images, "\tlabel=\"$label\"\n");
if (-e "/boot/initrd.img-$version-$complement")
{
push (@images, "\tinitrd=/boot/initrd.img-$version-$complement\n");
}
elsif (-e "/boot/initrd.img-$version")
{
push (@images, "\tinitrd=/boot/initrd.img-$version\n");
}
push (@images, "\tread-only\n");
push (@images, "\n");
$count++;
}
if (-e "/boot/memtest86.bin")
{
push (@images, "image=/boot/memtest86.bin\n");
push (@images, "\tlabel=\"Memory Test\"\n");
push (@images, "\tread-only\n");
push (@images, "\n");
}
if (-e "/boot/memtest86+.bin")
{
push (@images, "image=/boot/memtest86+.bin\n");
push (@images, "\tlabel=\"Memory Test+\"\n");
push (@images, "\tread-only\n");
push (@images, "\n");
}
return @images;
}
sub asky
{
do
{
print STDERR @_,"? [Yes] ";
$answer=<STDIN>;
}
while ($answer ne "\n" && !($answer =~ /^[YyNn].*/));
&ruler ();
return ( !($answer =~ /^[nN].*/) );
}
sub askn
{
do
{
print STDERR @_,"? [No] ";
$answer=<STDIN>;
}
while ($answer ne "\n" && !($answer =~ /^[YyNn].*/));
&ruler ();
return ( $answer =~ /^[yY].*/ );
}
sub compatibility_check
{
# Check a lilo.conf for options which are not compatible
# with the current version of lilo, and return 1 if any
# incompatible usages are found.
# This currently just checks for use of the any_* loaders.
system ("egrep '^[^#]*any_' $LILOCONF");
return 1 if ($? == 0);
return 0;
}
sub safe_system($)
{
# Works like system(), but just echoes the command that would
# be run if $DEBUG is 1.
if ($DEBUG) {
print STDERR "[Would have run: ", join(' ', @_), "]\n";
$? = 0;
}
else
{
system($_[0].">&2");
}
}
#####################################
# Actual work is done below here...
#####################################
# Debian's 'base' filesystem is a special case -- it's prebuilt
# by installing and configuring packages into a subdirectory,
# which is then made into a tarball, which is then used to
# make the initial filesystem for a fresh Debian install.
# Thus we can't actually run LILO now, because we know nothing
# of the disk layout. That will be done as part of the install
# process.
if ($configuring_base)
{
input("high","liloconfig/configuring_base");
go();
exit(0);
}
if ($liloconf_exists)
{
# Trust and use the existing lilo.conf.
# FIX: If the current lilo.conf installs a master boot record, ask
# to edit it to a partition boot record and install the master boot
# record to chain to that.
input("high","liloconfig/liloconf_exists");
go();
if ($liloconf_incompatible)
{
input("high","liloconfig/liloconf_incompatible");
go();
exit(1);
}
set("liloconfig/use_current_lilo","true");
input("high","liloconfig/use_current_lilo");
go();
($ret,$val)=get("liloconfig/use_current_lilo");
if ($val eq "true")
{
input("high","liloconfig/lilo_warning");
go();
stop();
&safe_system("/sbin/lilo -v");
if ( $? == 0 )
{
exit(0);
}
input("high","liloconfig/lilo_error");
go();
exit(1);
}
else
{
set("liloconfig/wipe_old_liloconf","false");
input("high","liloconfig/wipe_old_liloconf");
go();
($ret,$val)=get("liloconfig/wipe_old_liloconf");
if($val eq "true")
{
rename($LILOCONF, "$LILOCONF.OLD") or die "liloconfig: couldn't save old $LILOCONF as $LILOCONF.OLD: $!\n";
}
else
{
input("high","liloconfig/no_changes");
go();
exit(0);
}
}
}
# ASSERT: that we get here only if there is no lilo.conf or the user
# asked us to wipe out the old one...
# We make checks for broken fstabs and odd devices only if we are
# going to try to write a lilo.conf for the user.
if ($fstab_broken)
{
input("high","liloconfig/fstab_broken");
go();
exit(1);
}
if ($odd_fstab)
{
subst("liloconfig/odd_fstab","device",$device);
input("high","liloconfig/odd_fstab");
go();
exit(1);
}
input("high","liloconfig/instruction");
go();
# Flag so we can print STDERR a warning if we fell out the bottom of the config
# without having run lilo at all.
$lilorun = 0; $madeactive = 0;
subst("liloconfig/install_from_root_device","device",$device);
set("liloconfig/install_from_root_device","false");
input("high","liloconfig/install_from_root_device");
go();
($ret,$val)=get("liloconfig/install_from_root_device");
if($val eq "true")
{
umask(077);
open(CONF, ">$LILOCONF") or die "Couldn't open $LILOCONF for writing: $!\n";
if (!chown(0, 0, "$LILOCONF"))
{
die "Couldn't make $LILOCONF owned by root.root: $!\n" unless $DEBUG;
# Following message is only shown if $DEBUG is set. So, I do not care
# about templating it. Let it goes into STDERR. YMMV. <arturcz@hell.pl>
print STDERR "Oops, couldn't make $LILOCONF owned by root.root. Since you\n";
print STDERR "have set the DEBUG flag, I'm going to assume this is because\n";
print STDERR "you're running liloconfig as a normal user, and continue anyway.\n";
}
print CONF @header;
input("high","liloconfig/install_from_root_device");
go();
($ret,$val)=get("liloconfig/install_from_root_device");
if($val eq "true")
{
print CONF "# This allows booting from any partition on disks with more than 1024\n";
print CONF "# cylinders.\n";
print CONF "lba32\n";
print CONF "\n";
}
@middle_boilerplate = &get_images;
@bmp_boilerplate = &get_bitmap;
print CONF @bootheader, "boot=".$device, "\n", @rootheader, "root=".$device, "\n", @bmp_boilerplate, @boilerplate1, @middle_boilerplate, @boilerplate2;
close(CONF) or die "Couldn't close $LILOCONF: $!\n";
&safe_system("/sbin/lilo");
if ($? != 0)
{
input("high","liloconfig/lilo_error");
go();
exit(1);
}
$lilorun = 1;
}
subst("liloconfig/install_mbr","disk",$disk);
set("liloconfig/install_mbr","false");
input("high","liloconfig/install_mbr");
go();
($ret,$val)=get("liloconfig/install_mbr");
if($val eq "true")
{
&safe_system("install-mbr $disk");
if ($? != 0)
{
input("high","liloconfig/mbr_error");
go();
exit(1);
}
}
subst("liloconfig/make_active_partition","device",$device);
input("high","liloconfig/make_active_partition");
go();
($ret,$val)=get("liloconfig/install_mbr");
if($val eq "true")
{
my $part_num = $partition;
$part_num =~ s/^.*[a-z]//;
print STDERR "Activating Partition $part_num on disk $disk.\n";
&safe_system("/sbin/activate $disk $part_num");
if ($? != 0)
{
input("high","liloconfig/activate_error");
go();
exit(1);
}
$madeactive = 1;
}
# Trailer: summarise what we've done
print STDERR "\n";
if (! $lilorun)
{
print STDERR "WARNING: you will have to set up LILO manually to ensure that\n";
print STDERR " your system can be booted successfully!\n";
print STDERR "You can rerun liloconfig at any time if you change your mind and\n";
print STDERR "wish to use the default configuration.\n";
}
elsif ($madeactive)
{
# LILO was run and Linux partition made active
print STDERR "LILO successfully configured; Linux will be booted by default.\n";
print STDERR "If you installed the master boot record, you can boot a different\n";
print STDERR "OS by holding down the shift key as the system boots, and then\n";
print STDERR "pressing the key corresponding to the partition containing that\n";
print STDERR "OS when you see the \"1234F:\" prompt.\n";
}
else
{
my $part_num = $partition;
$part_num =~ s/^.*[a-z]//;
# LILO run, but Linux partition not made active
print STDERR "OK. If you installed the master boot record, and the partition\n";
print STDERR "boot record, you may boot Linux by holding down the shift key\n";
print STDERR "as the system boots, and then pressing the $part_num key\n";
print STDERR "when you see the \"1234F:\" prompt.\n";
}
print STDERR "\n";
print STDERR "For more information about LILO, see the documentation in\n";
print STDERR "/usr/share/doc/lilo/. For details about the MBR, see also\n";
print STDERR "/usr/share/doc/mbr/.\n";
exit(0);